package indi.zjh.dp.access;

import java.io.IOException;

import indi.zjh.dp.util.RedisUtil;
import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.Channel;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelOption;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import io.netty.handler.codec.http.HttpRequestDecoder;
import io.netty.handler.codec.http.HttpResponseEncoder;

public class HttpServer {
	
	protected EventLoopGroup bossGroup;
	protected EventLoopGroup workerGroup;
	protected Channel channel;
	protected boolean isRunning = false;
	
	public void start(int port) throws Exception
	{
		if(this.isRunning)
			return;
		this.bossGroup = new NioEventLoopGroup();
		this.workerGroup = new NioEventLoopGroup();
		try
		{
			ServerBootstrap b = new ServerBootstrap();
			b.group(this.bossGroup, this.workerGroup);
			b.channel(NioServerSocketChannel.class);
			b.childHandler(new ChannelInitializer<SocketChannel>(){

				@Override
				protected void initChannel(SocketChannel ch) throws Exception {
					// TODO Auto-generated method stub
					ch.pipeline().addLast(new HttpResponseEncoder());
					ch.pipeline().addLast(new HttpRequestDecoder());
					ch.pipeline().addLast(new HttpServerHandler(HttpServer.this));
				}
				
			});
			b.option(ChannelOption.SO_BACKLOG, 128);
			b.childOption(ChannelOption.SO_KEEPALIVE, true);
			ChannelFuture f = b.bind(port).sync();
			//f.channel().closeFuture().sync();
			this.channel = f.channel();
			RedisUtil.init();
		}
		finally
		{
			//this.workerGroup.shutdownGracefully();
			//this.bossGroup.shutdownGracefully();
			this.isRunning = true;
		}
	}
	
	public void stop() throws IOException
	{
		if(this.isRunning == false)
			return;
		this.channel.close();
		this.workerGroup.shutdownGracefully();
		this.bossGroup.shutdownGracefully();
		this.isRunning = false;
		RedisUtil.finish();
	}
}
